Completed
Push — master ( f40fe1...c58291 )
by Albert
04:55 queued 02:43
created

DragAndDrop.handleDragLeave   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 9
rs 9.6666

1 Function

Rating   Name   Duplication   Size   Complexity  
A 0 7 2
1
const Fieldset = {
2
  LAST_FORM_QUERY: '.code-form--file:last-of-type',
3
4
  addNew() {
5
    const lastForm = document.querySelector(this.LAST_FORM_QUERY);
6
    const newForm = this.getElement();
7
    const formsWrapper = lastForm.parentNode;
8
9
    formsWrapper.insertBefore(newForm, lastForm.nextSibling);
10
  },
11
12
  getElement() {
13
    const index = this.getNextIndex();
14
    const fieldset = document.createElement('fieldset');
15
    fieldset.setAttribute('class', 'code-form--file');
16
    fieldset.setAttribute('data-index', index);
17
18
    fieldset.innerHTML =
19
      `<label class="code-form--label" for="name[${index}]">Nazwa pliku (opcjonalna)</label>
20
       <input type="text" id="name[${index}]" name="name[${index}]" class="code-form--control">
21
       <label for="content[${index}]" class="code-form--label">Treść pliku</label>
22
       <textarea name="content[${index}]" id="content[${index}]" rows="10" class="code-form--control code-form--control__textarea"></textarea>`;
23
24
    return fieldset;
25
  },
26
27
  getNextIndex() {
28
    const currentIndex = parseInt(document.querySelector(this.LAST_FORM_QUERY).getAttribute('data-index'), 10);
29
30
    return currentIndex + 1;
31
  },
32
};
33
34
const NewFormButton = {
35
  BUTTON_QUERY: '#new-file',
36
37
  init() {
38
    const button = document.querySelector(this.BUTTON_QUERY);
39
    button.addEventListener('click', () => this.onClick());
40
  },
41
42
  onClick() {
43
    Fieldset.addNew();
44
  },
45
};
46
47
const DragAndDrop = {
48
  FILE_FORM_QUERY: '.code-form--file',
49
  OVERLAY_WRAPPER_QUERY: '.main',
50
51
  init() {
52
    this.lastTarget = null;
53
54
    this.appendOverlay();
55
    this.handleDragEnter();
56
    this.handleDragLeave();
57
    this.handleDragOver();
58
    this.handleDrop();
59
  },
60
61
  handleDragEnter() {
62
    window.addEventListener('dragenter', (event) => {
63
      if (this.isFile(event)) {
64
        this.lastTarget = event.target;
65
        this.showOverlay();
66
      }
67
    });
68
  },
69
70
  handleDragLeave() {
71
    window.addEventListener('dragleave', (event) => {
72
      event.preventDefault();
73
74
      if (event.target === this.lastTarget) {
75
        this.hideOverlay();
76
      }
77
    });
78
  },
79
80
  handleDragOver() {
81
    window.addEventListener('dragover', (event) => {
82
      event.preventDefault();
83
    });
84
  },
85
86
  handleDrop() {
87
    window.addEventListener('drop', (event) => {
88
      event.preventDefault();
89
      this.hideOverlay();
90
91
      const files = [...event.dataTransfer.files]
92
          .filter(file => this.isReadable(file));
93
94
      if (files.length === 0) {
95
        return;
96
      }
97
98
      const fieldsetsToCreateNumber = files.length - this.getEmptyFieldsets().length;
99
      this.createNewFieldsets(fieldsetsToCreateNumber);
100
101
      const emptyFieldsets = this.getEmptyFieldsets();
102
      emptyFieldsets.forEach((fieldset, index) => this.fillFieldset(fieldset, files[index]))
103
    });
104
  },
105
106
  createNewFieldsets(number) {
107
    for(let i = 0; i < number; i++) {
108
      Fieldset.addNew();
109
    }
110
  },
111
112
  fillFieldset(fieldset, file) {
113
    const input = fieldset.querySelector('input');
114
    const textarea = fieldset.querySelector('textarea');
115
116
    input.value = this.getFileName(file);
117
118
    this.getFileContent(file).then(content => {
119
      textarea.value = content;
120
    });
121
  },
122
123
  getEmptyFieldsets() {
124
    const fieldsets = [...document.querySelectorAll(this.FILE_FORM_QUERY)];
125
126
    return fieldsets.filter(fieldset => this.isFieldsetEmpty(fieldset));
127
  },
128
129
  isFieldsetEmpty(fieldset) {
130
    const inputValue = fieldset.querySelector('input').value;
131
    const textareaValue = fieldset.querySelector('textarea').value;
132
133
    return inputValue + textareaValue === '';
134
  },
135
136
  isFile(event) {
137
    return event.dataTransfer.types.some(type => type === 'Files');
138
  },
139
140
  isReadable(file) {
141
    // Is it empty string, application/* or text/*?
142
    return /(^$|application\/.+|text\/.+)/.exec(file.type);
143
  },
144
145
  getFileName(file) {
146
    return file.name;
147
  },
148
149
  getFileContent(file) {
150
    return new Promise(resolve => {
151
      const fileReader = new FileReader();
0 ignored issues
show
Bug introduced by
The variable FileReader seems to be never declared. If this is a global, consider adding a /** global: FileReader */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
152
153
      fileReader.readAsText(file);
154
      fileReader.onload = (event) => {
155
        resolve(event.target.result);
156
      };
157
    });
158
  },
159
160
  getOverlayElement() {
161
    const overlay =  document.createElement('div');
162
    overlay.classList.add('drop-overlay');
163
    overlay.innerHTML = `<p class="drop-overlay--text">Upuść pliki tutaj</p>`;
164
165
    return overlay;
166
  },
167
168
  appendOverlay() {
169
    const overlayWrapper = document.querySelector(this.OVERLAY_WRAPPER_QUERY);
170
    this.overlay = this.getOverlayElement();
171
172
    overlayWrapper.appendChild(this.overlay);
173
  },
174
175
  showOverlay() {
176
    this.overlay.classList.add('drop-overlay__active');
177
  },
178
179
  hideOverlay() {
180
    this.overlay.classList.remove('drop-overlay__active');
181
  },
182
};
183
184
DragAndDrop.init();
185
NewFormButton.init();
186